from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QPen, QFont
from PyQt5.QtCore import Qt, QRect, QPoint, QSize
from typing import NamedTuple
import sys

class QCpuTaskItem(NamedTuple):
    bg_color: str
    fg_color: str
    text: str


class QCpuTaskList(QWidget):
    def __init__(self, tasks: list[QCpuTaskItem], arrow_position: int=0, parent=None):
        super().__init__(parent)
        self.__tasks = tasks
        self.__arrow_position = arrow_position
        self.square_size = 45
        self.spacing = 1
        self.setMinimumHeight(self.square_size * 2 + 30)  # 增加高度以容纳编号
        self.setMinimumWidth(len(tasks) * (self.square_size + self.spacing))

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setFont(self.font())
        for i, task in enumerate(self.__tasks):
            x = i * (self.square_size + self.spacing)
            rect = QRect(x, 0, self.square_size, self.square_size)
            painter.fillRect(rect, QColor(task.bg_color))
            painter.setPen(QPen(QColor(task.fg_color)))
            painter.drawText(rect, Qt.AlignmentFlag.AlignCenter, task.text)
            
            # 绘制编号
            number_rect = QRect(x, self.square_size + 5, self.square_size, 20)
            painter.setPen(QPen(QColor('black')))
            painter.drawText(number_rect, Qt.AlignmentFlag.AlignCenter, str(i + 1))

        # 箭头
        if not self.tasks:
            return
        arrow_x = self.__arrow_position * (self.square_size + self.spacing)
        arrow_y = self.square_size + 30
        painter.setPen(QPen(QColor('black'), 2))
        # 箭头竖线
        painter.drawLine(
            arrow_x + self.square_size // 2,
            arrow_y,
            arrow_x + self.square_size // 2,
            arrow_y + self.square_size // 2
        )
        # 箭头左边的斜线
        painter.drawLine(
            arrow_x + self.square_size // 2,
            arrow_y ,
            arrow_x + self.square_size // 2 - 5,
            arrow_y  + 5
        )
        # 箭头右边的斜线
        painter.drawLine(
            arrow_x + self.square_size // 2,
            arrow_y ,
            arrow_x + self.square_size // 2 + 5,
            arrow_y  + 5
        )

    def sizeHint(self):
        return QSize(
            self.square_size * len(self.__tasks) + self.spacing * (len(self.__tasks) - 1),
            self.square_size * 2 + 30
        )
        
    def minimumSizeHint(self) -> QSize:
        print(self.square_size * len(self.__tasks) + self.spacing * (len(self.__tasks) - 1))
        return QSize(
            self.square_size * len(self.__tasks) + self.spacing * (len(self.__tasks) - 1),
            self.square_size * 2 + 30
        )
        
    def maximumSizeHint(self) -> QSize:
        return QSize(
            self.square_size * len(self.__tasks) + self.spacing * (len(self.__tasks) - 1),
            self.square_size * 2 + 30
        )
    
    @property
    def tasks(self):
        return self.__tasks
    
    @tasks.setter
    def tasks(self, tasks):
        self.__tasks = tasks
        self.update()
    
    @property
    def arrow_position(self):
        return self.__arrow_position
    
    @arrow_position.setter
    def arrow_position(self, position):
        self.__arrow_position = position
        self.update()
        
    def append_task(self, task: QCpuTaskItem):
        self.__tasks.append(task)
        self.update()
    
    def clear(self):
        self.__tasks.clear()
        self.update()

if __name__ == '__main__':
    from colors import random_color
    app = QApplication(sys.argv)
    tasks = [
        QCpuTaskItem(random_color(), 'white', 'A'),
        QCpuTaskItem(random_color(), 'white', 'B'),
        QCpuTaskItem(random_color(), 'white', 'C'),
        QCpuTaskItem(random_color(), 'white', 'D')
    ]
    window = QCpuTaskList(tasks, 2)
    # Segoe UI 
    window.setFont(QFont('Segoe UI', 12, QFont.Weight.Bold))
    window.show()
    sys.exit(app.exec_())